/**
 * 阳历转农历节日或日期
 * this.lunarDay 截取后的
 * this.lunarDays 全称
 * 如果返回的是日期那么this.lunarDays为""
 */
function LunarDay(year,month,day){
	cld = new calendar(year,month);
	for(var i=0;i<42;i++){
		var sD = i - cld.firstWeek;
		if(sD>-1 && sD<cld.length&&(sD+1)==day){
			this.lunarDay = (cld[sD].lDay==1 ? (cMonth(cld[sD].lMonth) + '月') : cDay(cld[sD].lDay))
			this.lunarDays = "";
			
			this.isYearHoliday = (cld[sD].color == "holiday" ? true : false);
			var s=cld[sD].lunarFestival;
			var ds=s;
			if(s.length>0){
				s = s.length>4 ? (s.substr(0, 3) + '…') : s;
			}else{
				ds = s = cld[sD].solarFestival;
				if(s.length>0){
					s = s.length>4 ? (s.substr(0, 3) + '…') : s;
				}else{
					ds = s = cld[sD].solarTerms;
					s = s.length>4 ? (s.substr(0, 3) + '…') : s;
				}
			}
			if(s.length>0){
				this.lunarDay = s;
				this.lunarDays = ds;
			}
			break;
		}
	}
}

function cMonth(month){
	switch(month){
		case 1:
			return "元";
		case 2:
			return "二";
		case 3:
			return "三";
		case 4:
			return "四";
		case 5:
			return "五";
		case 6:
			return "六";
		case 7:
			return "七";
		case 8:
			return "八";
		case 9:
			return "九";
		case 10:
			return "十";
		case 11:
			return "十一";
		case 12:
			return "十二";
		
	}
}
/**
 * 以下为日历相关方法
 */
var lunarInfo = new Array(0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950,
		0x16554, 0x056a0, 0x09ad0, 0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250,
		0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0,
		0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
		0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0,
		0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0,
		0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 0x15355, 0x04da0,
		0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50,
		0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,
		0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540,
		0x0b5a0, 0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50,
		0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3,
		0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960, 0x0d954,
		0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,
		0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176,
		0x052b0, 0x0a930, 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6,
		0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7,
		0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0,
		0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0);
var solarMonth=new Array(31,28,31,30,31,30,31,31,30,31,30,31);
var sTermInfo = new Array(0,21208,42467,63836,85337,107014,128867,150921,173149,195551,218072,240693,263343,285989,308563,331033,353350,375494,397447,419210,440795,462224,483532,504758)
var monthName = new Array("JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC");
var Gan=new Array("甲","乙","丙","丁","戊","己","庚","辛","壬","癸");
var Zhi=new Array("子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥");
var Animals=new Array("鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪");
var solarTerm = new Array("小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至")
var nStr1 = new Array('日','一','二','三','四','五','六','七','八','九','十')
var nStr2 = new Array('初','十','廿','卅','　');
//国历节日 *表示放假日
var sFtv = new Array(
		"0101*元旦",
		"0214 情人节",
		"0308 妇女节",
		"0312 植树节",
		"0401 愚人节",
		"0501 劳动节",
		"0504 青年节",
		"0601 儿童节",
		"0701 建党日",
		"0801 建军节",
		"0910 教师节",
		"1001*国庆节",
		"1225 圣诞节");
//农历节日 *表示放假日
var lFtv = new Array(
		"0101*春节",
		"0115 元宵节",
		"0505*端午节",
		"0815*中秋节",
		"0909 重阳节",
		"1208 腊八节",
		"0100 除夕");
/**
 * 某月的第几个星期几
 * "0520 母亲节"
 * 05 表示五月
 * 2  表示第二个星期
 * 0  表示星期几
 */
var wFtv = new Array("0520 母亲节","0630 父亲节","1144 感恩节");
/**
 * 传回农历y年的总天数
 */
function lYearDays(y){
	var i, sum = 348;
	for(i=0x8000; i>0x8; i>>=1)
		sum += (lunarInfo[y-1900] & i)? 1: 0;
	return(sum+leapDays(y));
}
/**
 * 传回农历 y年闰月的天数
 */
function leapDays(y){
	if(leapMonth(y))
		return ((lunarInfo[y-1900] & 0x10000)? 30: 29);
	else
		return 0;
}
/**
 * 传回农历 y年闰哪个月 1-12 , 没闰传回 0
 */
function leapMonth(y){
	return (lunarInfo[y-1900] & 0xf);
}
/**
 * 传回农历 y年m月的总天数
 */
function monthDays(y,m){
	return ((lunarInfo[y-1900] & (0x10000>>m))? 30 : 29);
}
/**
 * 传回国历 y年某m+1月的天数
 */
function solarDays(y,m){
	if(m==1)
		return (((y%4 == 0) && (y%100 != 0) || (y%400 == 0))? 29 : 28);
	else
		return solarMonth[m];
}
/**
 * 传入 offset 传回干支, 0=甲子
 */
function cyclical(num){
	return (Gan[num%10]+Zhi[num%12]);
}
/**
 * 某年的第n个节气为几日(从0小寒起算)
 */
function sTerm(y,n){
	var offDate = new Date((31556925974.7*(y-1900) + sTermInfo[n]*60000) + Date.UTC(1900,0,6,2,5));
	return offDate.getUTCDate();
}
/**
 * 算出农历, 传入日期, 传回农历日期
 * 属性有 
 * .year	农历年
 * .month   农历月
 * .day 	农历日
 * .isLeap 	是否为农历闰月
 * .yearCyl 农历年与1864年相差数
 * .dayCyl 1900年1月31日以来的闰月数
 * .monCyl 1900年1月31日以来相差的天数在加上40
 */
function Lunar(objDate){
	var i, leap=0, temp=0;
	var baseDate = new Date(1900,0,31);
	var offset = (objDate - baseDate)/86400000;
	this.dayCyl = offset + 40;
	this.monCyl = 14;
	for(i=1900; i<2050 && offset>0;i++){
		temp = lYearDays(i);
		offset -= temp;
		this.monCyl += 12;
	}
	if(offset<0){
		offset += temp;
		i--;
		this.monCyl -= 12;
	}
	this.year = i;
	this.yearCyl = i-1864;
	leap = leapMonth(i);
	this.isLeap = false;
	for(i=1; i<13 && offset>0; i++){
		if(leap>0&&i==(leap+1)&&this.isLeap==false){
			--i;
			this.isLeap = true;
			temp = leapDays(this.year);
		}else{
			temp = monthDays(this.year, i);
		}
		if(this.isLeap==true&&i==(leap+1))
			this.isLeap = false;
		offset -= temp;
		if(this.isLeap == false)
			this.monCyl++;
	}
	if(offset==0&&leap>0&&i==leap+1){
		if(this.isLeap){
			this.isLeap = false;
		}else{
			this.isLeap = true;
			--i;
			--this.monCyl;
		}
	}
	if(offset<0){
		offset += temp;
		--i;
		--this.monCyl;
	}
	this.month = i;
	this.day = offset + 1;
}
/**
 * 月历属性
 */
function calElement(sYear,sMonth,sDay,week,lYear,lMonth,lDay,isLeap,cYear,cMonth,cDay){
	this.isToday = false;
	// 国历
	this.sYear = sYear;
	this.sMonth = sMonth;
	this.sDay = sDay;
	this.week = week;
	// 农历
	this.lYear = lYear;
	this.lMonth = lMonth;
	this.lDay = lDay;
	this.isLeap = isLeap;
	// 干支
	this.cYear = cYear;
	this.cMonth = cMonth;
	this.cDay = cDay;

	this.color = '';

	this.lunarFestival = ''; // 农历节日
	this.solarFestival = ''; // 国历节日
	this.solarTerms = ''; // 节气
}
/**
 * var cld;
 * for(var i=0;i<12;i++){
 * 		cld = new calendar(year,month);
 * 		for(var j=0;j<42;j++){
 * 			var sD = j - cld.firstWeek;	//year月month月一号在星期几
 * 			if(sD>-1 && sD<cld.length){
 * 				阳历cld[sD].sYear年cld[sD].sMonth月cld[sD].sDay日 星期cld[sD].week
 * 				阴历cld[sD].lYear年cld[sD].lMonth月cld[sD].lDay日 cld[sD].isLeap是否为农历闰月
 * 				cld[sD].color节日颜色
 * 				cld[sD].lunarFestival 农历节日
 * 				cld[sD].solarFestival 国历节日
 * 				cld[sD].solarTerms 节气
 * 			}
 * 		}
 * }
 * 传回月历 (y年,m+1月)
 */
function calendar(y, m) {
	var sDObj, lDObj, lY, lM, lD = 1, lL, lX = 0, tmp1, tmp2;
	var lDPOS = new Array(3);
	var n = 0;
	var firstLM = 0;
	sDObj = new Date(y, m, 1); // 当月一日日期
	this.length = solarDays(y, m); // 国历当月天数
	this.firstWeek = sDObj.getDay(); // 国历当月1日星期几
	for ( var i = 0; i < this.length; i++) {
		if (lD > lX) {
			sDObj = new Date(y, m, i + 1); // 当月一日日期
			lDObj = new Lunar(sDObj); // 农历
			lY = lDObj.year; // 农历年
			lM = lDObj.month; // 农历月
			lD = lDObj.day; // 农历日
			lL = lDObj.isLeap; // 农历是否闰月
			lX = lL ? leapDays(lY) : monthDays(lY, lM); // 农历当月最後一天
			if (n == 0)
				firstLM = lM;
			lDPOS[n++] = i - lD + 1;
		}
		this[i] = new calElement(y, m + 1, i + 1, nStr1[(i + this.firstWeek) % 7], lY, lM, lD++, lL, cyclical(lDObj.yearCyl), cyclical(lDObj.monCyl), cyclical(lDObj.dayCyl++));
		if ((i + this.firstWeek) % 7 == 0)
			this[i].color = 'weekend'; // 周日颜色
//		if ((i + this.firstWeek) % 14 == 13)
//			this[i].color = 'weekend'; // 周休二日颜色
	}
	// 节气
	tmp1 = sTerm(y, m * 2) - 1;
	tmp2 = sTerm(y, m * 2 + 1) - 1;
	this[tmp1].solarTerms = solarTerm[m * 2];
	this[tmp2].solarTerms = solarTerm[m * 2 + 1];
	if (m == 3)
		this[tmp1].color = 'holiday'; // 清明颜色

	// 国历节日
	for (i in sFtv)
		if (sFtv[i].match(/^(\d{2})(\d{2})([\s\*])(.+)$/))
			if (Number(RegExp.$1) == (m + 1)) {
				this[Number(RegExp.$2) - 1].solarFestival += RegExp.$4 + ' ';
				if (RegExp.$3 == '*')
					this[Number(RegExp.$2) - 1].color = 'holiday';
			}
	// 月周节日
	for (i in wFtv)
		if (wFtv[i].match(/^(\d{2})(\d)(\d)([\s\*])(.+)$/))
			if (Number(RegExp.$1) == (m + 1)) {
				tmp1 = Number(RegExp.$2);
				tmp2 = Number(RegExp.$3);
				this[((this.firstWeek > tmp2) ? 7 : 0) + 7 * (tmp1 - 1) + tmp2 - this.firstWeek].solarFestival += RegExp.$5 + '';
			}
	// 农历节日
	for (i in lFtv)
		if (lFtv[i].match(/^(\d{2})(.{2})([\s\*])(.+)$/)) {
			tmp1 = Number(RegExp.$1) - firstLM;
			if (tmp1 == -11)
				tmp1 = 1;
			if (tmp1 >= 0 && tmp1 < n) {
				tmp2 = lDPOS[tmp1] + Number(RegExp.$2) - 1;
				if (tmp2 >= 0 && tmp2 < this.length) {
					this[tmp2].lunarFestival += RegExp.$4 + ' ';
					if (RegExp.$3 == '*')
						this[tmp2].color = 'holiday';
				}
			}
		}
	// 今日
	if(typeof(tY) != "undefined" && typeof(tM) != "undefined"&&typeof(tD) != "undefined"){
		if (y == tY && m == tM)
			this[tD - 1].isToday = true;
	}
}
/**
 * 中文日期
 */
function cMonth(month){
	var chineseNumber = new Array("一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二");
	return chineseNumber[month-1] ;
}


/**
 * 中文日期
 */
function cDay(day){
	var chineseNumber = new Array("一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二");
	var chineseTen = new Array("初", "十", "廿", "卅");
    var n = day % 10 == 0 ? 9 : day % 10 - 1;
    if (day > 30)
        return "";
    if (day == 10)
        return "初十";
    else
        return chineseTen[Math.floor(day / 10)] + chineseNumber[n];
	
}

/**
 * month:0~11
 * day:1~31
 * weeknum:1~53
 * weekday:1~7 1:周日
 */
function getMinorDay(lunaryear,lunarmonth,lunarday,month,day,weekofmonth,weekday){
	var re="";
	var isstop=false;
	//判断国历节日
	for (i in sFtv){
		if (sFtv[i].match(/^(\d{2})(\d{2})([\s\*])(.+)$/)){
			if (Number(RegExp.$1) == (month + 1)&&Number(RegExp.$2)==day) {
				re=RegExp.$4;
				isstop=true;
				break;
			}
		}
	}
	if(isstop)
		return re;
	
	//判断周历节日
	for (i in wFtv){
		
		if (wFtv[i].match(/^(\d{2})(\d)(\d)([\s\*])(.+)$/)){
			
			if (Number(RegExp.$1) ==(month+1)&&Number(RegExp.$2)==weekofmonth&&Number(RegExp.$3)==(weekday-1)) {
				re=RegExp.$4;
				isstop=true;
				break;
			}
		}
	}
	
	if(isstop)
		return re;
	
	if(lunarmonth==12){
		var daysoflast=monthDays(lunaryear, lunarmonth);
		if(lunarday==daysoflast)
			return "除夕";
	}
	
	
	for (i in lFtv){
		if (lFtv[i].match(/^(\d{2})(.{2})([\s\*])(.+)$/)) {
			var tmp1 = Number(RegExp.$1);
			var tmp2= Number(RegExp.$2);
			if(tmp1==lunarmonth&&tmp2==lunarday){
				re=RegExp.$4;
				isstop=true;
				break;
			}
		}
	}
	
	if(isstop)
		return re;
	
	var ml=cMonth(lunarmonth);
	if(lunarday==1)
		return ml+"月";
	else{
		var chineseNumber = new Array("一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二");
		var chineseTen = new Array("初", "十", "廿", "卅");
		switch (lunarday) {      
			case 10:re = '初十'; break;      
			case 20:re = '二十'; break;      
			case 30:re = '三十'; break;      
			default:re = chineseTen[Math.floor(lunarday/10)]; re += chineseNumber [lunarday%10-1];      
		}
		return re;
	}

}


function day_of_week2cn(day){
	var str=null;
	switch (day) {
	case 0:
		str="星期日";
		break;
	case 1:
		str="星期一";
		break;
	case 2:
		str="星期二";
		break;
	case 3:
		str="星期三";
		break;
	case 4:
		str="星期四";
		break;
	case 5:
		str="星期五";
		break;
	case 6:
		str="星期六";
		break;
	default:
		break;
	}
	return str;
}

/**     
* 对Date的扩展，将 Date 转化为指定格式的String     
* 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q) 可以用 1-2 个占位符     
* 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)     
* eg:     
* (new Date()).pattern("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423     
* (new Date()).pattern("yyyy-MM-dd E HH:mm:ss") ==> 2009-03-10 二 20:09:04     
* (new Date()).pattern("yyyy-MM-dd EE hh:mm:ss") ==> 2009-03-10 周二 08:09:04     
* (new Date()).pattern("yyyy-MM-dd EEE hh:mm:ss") ==> 2009-03-10 星期二 08:09:04     
* (new Date()).pattern("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18     
*/     
Date.prototype.pattern=function(fmt) {        
    var o = {        
    "M+" : this.getMonth()+1, //月份        
    "d+" : this.getDate(), //日        
    "h+" : this.getHours()%12 == 0 ? 12 : this.getHours()%12, //小时        
    "H+" : this.getHours(), //小时        
    "m+" : this.getMinutes(), //分        
    "s+" : this.getSeconds(), //秒        
    "q+" : Math.floor((this.getMonth()+3)/3), //季度        
    "S" : this.getMilliseconds() //毫秒        
    };        
    var week = {        
    "0" : "\u65e5",        
    "1" : "\u4e00",        
    "2" : "\u4e8c",        
    "3" : "\u4e09",        
    "4" : "\u56db",        
    "5" : "\u4e94",        
    "6" : "\u516d"       
    };        
    if(/(y+)/.test(fmt)){        
        fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));        
    }        
    if(/(E+)/.test(fmt)){        
        fmt=fmt.replace(RegExp.$1, ((RegExp.$1.length>1) ? (RegExp.$1.length>2 ? "\u661f\u671f" : "\u5468") : "")+week[this.getDay()+""]);        
    }        
    for(var k in o){        
        if(new RegExp("("+ k +")").test(fmt)){        
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));        
        }        
    }        
    return fmt;        
} 